// Copyright (C) 2024 wlly-lzh
// Created by wlly-lzh on 24-3-30
// Linked List Queue 基于链表的队列

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "linkedlist.c"

typedef struct LLinQueue LLinQueue;
struct LLinQueue {
	LinkedList *Head;
	LinkedList *Tail;
	int Size;
};

void Error_LLinQueue_Malloc();
void Error_LLinQueue_Null();

LLinQueue * Create_LLinQueue(){
	LLinQueue * newQueue;
	newQueue =(LLinQueue *)malloc(sizeof(LLinQueue));
	if(newQueue == NULL){
		Error_LLinQueue_Malloc();
		exit(3);
	}
	newQueue->Head=newQueue->Tail=NULL;
	newQueue->Size=0;
	return newQueue;
}
void Clear_LLinQueue(LLinQueue *Queue){
	if(Queue == NULL){
		Error_LLinQueue_Null();
		exit(4);
	}
	if(Queue->Size > 0){
		Clear_LinkedList(Queue->Head);
		Queue->Head=Queue->Tail=NULL;
		Queue->Size=0;
	}
}
void Destroy_LLinQueue(LLinQueue **Queue){
	Clear_LLinQueue(*Queue);
	free(*Queue);
	*Queue=NULL;
}
bool En_LLinQueue(LLinQueue *Queue,void *Data){
	if(Queue == NULL){
		Error_LLinQueue_Null();
		exit(4);
	}
	if(Data == NULL){
		Error_LLinQueue_Null();
		return false;
	}
	LinkedList *newList=(LinkedList *)malloc(sizeof(LinkedList));
	if(newList == NULL){
		Error_LLinQueue_Malloc();
		exit(3);
	}
	newList->Data=Data;
	newList->Next=NULL;
	if(Queue->Size > 0){
		Queue->Tail->Next=newList;
	}else{
		Queue->Head=newList;
	}
	Queue->Tail=newList;
	Queue->Size++;
	return true;
}
bool De_LLinQueue(LLinQueue *Queue,void **Data){
	if(Queue == NULL){
		Error_LLinQueue_Null();
		exit(4);
	}
	LinkedList *Del=Queue->Head;
	if(Queue->Size > 0){
		*Data=Queue->Head->Data;
		Queue->Head=Queue->Head->Next;
		free(Del);
		Queue->Size--;
		return true;
	}else{
#ifdef _LINUX_PLATFORM_
		printf("\033[31mliblds/LLinQueue: The Queue Is Empty!\033[0m\n");
#else
		printf("liblds/LLinQueue: The Queue Is Empty!\n");
#endif
		return false;
	}
}
bool IsEmpty_LLinQueue(const LLinQueue *Queue){
	if(Queue == NULL){
		Error_LLinQueue_Null();
		exit(4);
	}
	if(Queue->Size == 0)
		return true;
	else
		return false;
}
bool GetHead_LLinQueue(const LLinQueue *Queue,void ** Data){
	if(!IsEmpty_LLinQueue(Queue)){
		*Data=Queue->Head->Data;
		return true;
	}else
		return false;
}

#ifdef _LINUX_PLATFORM_
void Error_LLinQueue_Malloc(){
	printf("\033[31mliblds/LLinQueue: Malloc False!\033[0m\n");
}
void Error_LLinQueue_Null(){
	printf("\033[31mliblds/LLinQueue: The parameter is Null!\033[0m\n");
}
#else
void Error_LLinQueue_Malloc(){
	printf("liblds/LLinQueue: Malloc False!\n");
}
void Error_LLinQueue_Null(){
	printf("liblds/LLinQueue: The parameter is Null!\n");
}
#endif
